//使用数组实现一个  环形队列
//环形队列的最大容量为   数组容量-1

#include <iostream>
template <class T>
class MyQueue
{
public:
    MyQueue(int volume)
    {
        //做了一个小手脚，这样使得初始化的容量  等于  队列的实际容量
        this->volume = volume+1;
        //C++给数组开辟动态内存的正确写法
        arr = new T[volume];
    }
    bool isEmpty()
    {
        return (front==rear);
    }
    bool isFull()
    {
        return ((rear+1)%volume==front);
    }
    //向队尾中加入一个元素
    void push(T t1)
    {
        if (this->isFull()){
            std::cout<<"队列已满，无法添加元素！"<<std::endl;
            return;
        }
        arr[rear]=t1;
        rear=(rear+1)%volume;
        return;
    }
    //从队头取出一个元素
    T pop()
    {
        if (this->isEmpty()){
            std::cout<<"队列为空，无法取出！"<<std::endl;
            return 0;
        }
        T t1=arr[front];
        front=(front+1)%volume;
        return t1;
    }
    //显示队头的一个元素
    T getFront()
    {
        if (this->isEmpty()){
            std::cout<<"队列为空，无法取出！"<<std::endl;
            return 0;
        }
        return arr[front];
    }
    //显示队尾的元素
    T getBack()
    {   
        if (this->isEmpty()){
            std::cout<<"队列为空，无法取出！"<<std::endl;
            return 0;
        }
        return arr[(rear+volume-1)%volume];
    }   

    //在析构函数中，需要将类内部申请的内存释放
    ~MyQueue()
    {
        if (arr!=NULL){
            delete[] arr;
            arr=NULL;
        }
    }

private:
    int volume;
    T *arr;
    int front=0;
    int rear=0;

};
//测试代码   
int main(int argc, char** argv)
{
    MyQueue<int> queue(5);
    //初始化
    std::cout<<"将1 2 3 4 5加入队列"<<std::endl;
    queue.push(1);
    queue.push(2);
    queue.push(3);
    queue.push(4);
    queue.push(5);
    std::cout<<"查看队头和队尾元素"<<std::endl;
    std::cout<<queue.getFront()<<std::endl;
    std::cout<<queue.getBack()<<std::endl;
    std::cout<<"队列已满状况下，加入元素"<<std::endl;
    queue.push(6);
    std::cout<<"取队头元素"<<std::endl;
    std::cout<<queue.pop()<<std::endl;
    std::cout<<queue.pop()<<std::endl;
    std::cout<<"将6 7加入队列"<<std::endl;
    queue.push(6);
    queue.push(7);
    std::cout<<"取队头元素"<<std::endl;
    std::cout<<queue.pop()<<std::endl;
    std::cout<<queue.pop()<<std::endl;
    std::cout<<queue.pop()<<std::endl;
    std::cout<<queue.pop()<<std::endl;
}